package com.gitee.wsl.func.operator

import com.gitee.wsl.func.BiFunction



/**
 * Represents an operation upon two operands of the same type, producing a result
 * of the same type as the operands.  This is a specialization of
 * [BiFunction] for the case where the operands and the result are all of
 * the same type.
 *
 *
 * This is a [functional interface](package-summary.html)
 * whose functional method is [.apply].
 *
 * @param <T> the type of the operands and result of the operator
 *
 * @see BiFunction
 *
 * @see UnaryOperator
 *
 * @since 1.8
</T> */
fun interface BinaryOperator<T> : BiFunction<T, T, T> {
    companion object {
        /**
         * Returns a [BinaryOperator] which returns the lesser of two elements
         * according to the specified `Comparator`.
         *
         * @param <T> the type of the input arguments of the comparator
         * @param comparator a `Comparator` for comparing the two values
         * @return a `BinaryOperator` which returns the lesser of its operands,
         * according to the supplied `Comparator`
         * @throws NullPointerException if the argument is null
        </T> */
        fun <T> minBy(comparator: Comparator<in T>): BinaryOperator<T> {
            return BinaryOperator { a: T, b: T -> if (comparator.compare(a, b) <= 0) a else b }
        }

        /**
         * Returns a [BinaryOperator] which returns the greater of two elements
         * according to the specified `Comparator`.
         *
         * @param <T> the type of the input arguments of the comparator
         * @param comparator a `Comparator` for comparing the two values
         * @return a `BinaryOperator` which returns the greater of its operands,
         * according to the supplied `Comparator`
         * @throws NullPointerException if the argument is null
        </T> */
        fun <T> maxBy(comparator: Comparator<in T>): BinaryOperator<T> {
            return BinaryOperator { a: T, b: T -> if (comparator.compare(a, b) >= 0) a else b }
        }
    }
}
